"""
视频处理API蓝图
提供视频格式转换、压缩、信息获取等功能
"""

from flask import Blueprint, request, jsonify, send_file, current_app
import os
import logging
import json
from app.service.video_service import VideoService
from app.tools.utils import get_safe_filename, validate_file_extension

# 创建视频API蓝图
video_bp = Blueprint('video', __name__, url_prefix='/video')

def allowed_file(filename, allowed_extensions):
    """检查文件格式是否允许"""
    return validate_file_extension(filename, allowed_extensions)

def get_video_service():
    """获取视频服务实例"""
    return VideoService(current_app.config['UPLOAD_FOLDER'], current_app.config['OUTPUT_FOLDER'])

@video_bp.route('/convert', methods=['POST'])
def convert_format():
    """转换视频格式"""
    try:
        if 'video' not in request.files:
            return jsonify({'error': '没有上传视频文件'}), 400
        
        file = request.files['video']
        target_format = request.form.get('format', 'mp4')
        
        if file.filename == '':
            return jsonify({'error': '没有选择文件'}), 400
        
        if not allowed_file(file.filename, current_app.config['ALLOWED_EXTENSIONS']):
            return jsonify({'error': '不支持的文件格式'}), 400
        
        # 保存上传的文件
        filename = get_safe_filename(file.filename)
        temp_path = os.path.join(current_app.config['UPLOAD_FOLDER'], filename)
        file.save(temp_path)
        
        # 转换格式
        video_service = get_video_service()
        result = video_service.convert_format_service(temp_path, target_format)
        if not result['success']:
            return jsonify({'error': result['error']}), 500
        
        output_path = result['output_path']
        
        # 清理临时文件
        os.remove(temp_path)
        
        logging.info(f"输出路径: {output_path}")
        return send_file(output_path, as_attachment=True, download_name=f'converted_video.{target_format}')
    
    except Exception as e:
        logging.error(f"视频格式转换失败: {e}")
        return jsonify({'error': str(e)}), 500

@video_bp.route('/compress', methods=['POST'])
def compress_video():
    """压缩视频文件"""
    try:
        if 'video' not in request.files:
            return jsonify({'error': '没有上传视频文件'}), 400
        
        file = request.files['video']
        quality = request.form.get('quality', 'medium')
        
        if file.filename == '':
            return jsonify({'error': '没有选择文件'}), 400
        
        if not allowed_file(file.filename, current_app.config['ALLOWED_EXTENSIONS']):
            return jsonify({'error': '不支持的文件格式'}), 400
        
        # 保存上传的文件
        filename = get_safe_filename(file.filename)
        temp_path = os.path.join(current_app.config['UPLOAD_FOLDER'], filename)
        file.save(temp_path)
        
        # 压缩视频
        video_service = get_video_service()
        result = video_service.compress_video_service(temp_path, quality)
        if not result['success']:
            return jsonify({'error': result['error']}), 500
        
        output_path = result['output_path']
        
        # 清理临时文件
        os.remove(temp_path)
        
        return send_file(output_path, as_attachment=True, download_name='compressed_video.mp4')
    
    except Exception as e:
        logging.error(f"视频压缩失败: {e}")
        return jsonify({'error': str(e)}), 500

@video_bp.route('/info', methods=['POST'])
def get_video_info():
    """获取视频信息"""
    try:
        if 'video' not in request.files:
            return jsonify({'error': '没有上传视频文件'}), 400
        
        file = request.files['video']
        
        if file.filename == '':
            return jsonify({'error': '没有选择文件'}), 400
        
        if not allowed_file(file.filename, current_app.config['ALLOWED_EXTENSIONS']):
            return jsonify({'error': '不支持的文件格式'}), 400
        
        # 保存上传的文件
        filename = get_safe_filename(file.filename)
        temp_path = os.path.join(current_app.config['UPLOAD_FOLDER'], filename)
        file.save(temp_path)
        
        # 获取视频信息
        video_service = get_video_service()
        result = video_service.get_video_info_service(temp_path)
        if not result['success']:
            return jsonify({'error': result['error']}), 500
        
        info = result['video_info']
        
        # 清理临时文件
        os.remove(temp_path)
        
        return jsonify(info)
    
    except Exception as e:
        logging.error(f"获取视频信息失败: {e}")
        return jsonify({'error': str(e)}), 500

@video_bp.route('/mask', methods=['POST'])
def apply_mask():
    """应用遮挡到视频"""
    try:
        # 检查是否有视频文件
        if 'video' not in request.files:
            return jsonify({'error': '没有上传视频文件'}), 400
        
        file = request.files['video']
        if file.filename == '':
            return jsonify({'error': '没有选择文件'}), 400
        
        if not allowed_file(file.filename, current_app.config['ALLOWED_EXTENSIONS']):
            return jsonify({'error': '不支持的文件格式'}), 400
        
        # 检查是否有遮挡数据
        mask_data = request.form.get('mask_data')
        if not mask_data:
            return jsonify({'error': '没有提供遮挡数据'}), 400
        
        try:
            mask_info = json.loads(mask_data)
        except json.JSONDecodeError:
            return jsonify({'error': '遮挡数据格式错误'}), 400
        
        # 获取预览模式参数
        is_preview = request.form.get('is_preview', 'false').lower() == 'true'
        start_time = request.form.get('start_time', '0')  # 开始时间，秒为单位
        duration = request.form.get('duration', '5')  # 持续时间，秒为单位（默认5秒预览）
        
        # 验证时间参数
        try:
            start_time_seconds = float(start_time)
            duration_seconds = float(duration)
            if start_time_seconds < 0 or duration_seconds <= 0:
                return jsonify({'error': '时间参数必须为正数'}), 400
        except ValueError:
            return jsonify({'error': '时间参数格式错误'}), 400
        
        # 保存上传的视频文件
        filename = get_safe_filename(file.filename)
        video_path = os.path.join(current_app.config['UPLOAD_FOLDER'], filename)
        file.save(video_path)
        
        try:
            # 生成遮挡后的视频
            video_service = get_video_service()
            result = video_service.apply_mask_service(
                video_path, mask_info, is_preview, start_time_seconds, duration_seconds
            )
            
            if not result['success']:
                return jsonify({'error': result['error']}), 500
            
            output_path = result['output_path']
            
            # 清理临时文件
            os.remove(video_path)
            
            # 根据是否为预览模式设置不同的文件名
            download_name = 'masked_preview.mp4' if is_preview else 'masked_video.mp4'
            return send_file(output_path, as_attachment=True, download_name=download_name)
            
        except Exception as e:
            # 清理临时文件
            if os.path.exists(video_path):
                os.remove(video_path)
            raise e
    
    except Exception as e:
        logging.error(f"应用遮挡失败: {e}")
        return jsonify({'error': str(e)}), 500 

@video_bp.route('/add_background_music', methods=['POST'])
def add_background_music():
    """为视频添加背景音乐"""
    try:
        if 'video' not in request.files:
            return jsonify({'error': '没有上传视频文件'}), 400
        
        if 'music' not in request.files:
            return jsonify({'error': '没有上传音乐文件'}), 400
        
        video_file = request.files['video']
        music_file = request.files['music']
        
        if video_file.filename == '' or music_file.filename == '':
            return jsonify({'error': '没有选择文件'}), 400
        
        if not allowed_file(video_file.filename, current_app.config['ALLOWED_EXTENSIONS']):
            return jsonify({'error': '不支持的视频文件格式'}), 400
        
        if not allowed_file(music_file.filename, current_app.config['ALLOWED_AUDIO_EXTENSIONS']):
            return jsonify({'error': '不支持的音频文件格式'}), 400
        
        # 获取参数
        volume_ratio = float(request.form.get('volume_ratio', 0.3))
        loop_music = request.form.get('loop_music', 'true').lower() == 'true'
        
        # 保存上传的文件
        video_filename = get_safe_filename(video_file.filename)
        music_filename = get_safe_filename(music_file.filename)
        
        video_path = os.path.join(current_app.config['UPLOAD_FOLDER'], video_filename)
        music_path = os.path.join(current_app.config['UPLOAD_FOLDER'], music_filename)
        
        video_file.save(video_path)
        music_file.save(music_path)
        
        try:
            # 添加背景音乐
            video_service = get_video_service()
            result = video_service.add_background_music_service(video_path, music_path, volume_ratio, loop_music)
            
            if not result['success']:
                return jsonify({'error': result['error']}), 500
            
            output_path = result['output_path']
            
            # 清理临时文件
            os.remove(video_path)
            os.remove(music_path)
            
            return send_file(output_path, as_attachment=True, download_name='video_with_bg_music.mp4')
            
        except Exception as e:
            # 清理临时文件
            if os.path.exists(video_path):
                os.remove(video_path)
            if os.path.exists(music_path):
                os.remove(music_path)
            raise e
    
    except Exception as e:
        logging.error(f"添加背景音乐失败: {e}")
        return jsonify({'error': str(e)}), 500 

@video_bp.route('/add_background_music_with_options', methods=['POST'])
def add_background_music_with_options():
    """为视频添加背景音乐（带更多选项）"""
    try:
        if 'video' not in request.files:
            return jsonify({'error': '没有上传视频文件'}), 400
        
        if 'music' not in request.files:
            return jsonify({'error': '没有上传音乐文件'}), 400
        
        video_file = request.files['video']
        music_file = request.files['music']
        
        if video_file.filename == '' or music_file.filename == '':
            return jsonify({'error': '没有选择文件'}), 400
        
        if not allowed_file(video_file.filename, current_app.config['ALLOWED_EXTENSIONS']):
            return jsonify({'error': '不支持的视频文件格式'}), 400
        
        if not allowed_file(music_file.filename, current_app.config['ALLOWED_AUDIO_EXTENSIONS']):
            return jsonify({'error': '不支持的音频文件格式'}), 400
        
        # 获取参数
        volume_ratio = float(request.form.get('volume_ratio', 0.3))
        loop_music = request.form.get('loop_music', 'true').lower() == 'true'
        fade_in_duration = float(request.form.get('fade_in_duration', 0))
        fade_out_duration = float(request.form.get('fade_out_duration', 0))
        start_time = float(request.form.get('start_time', 0))
        end_time = request.form.get('end_time')
        if end_time:
            end_time = float(end_time)
        
        # 保存上传的文件
        video_filename = get_safe_filename(video_file.filename)
        music_filename = get_safe_filename(music_file.filename)
        
        video_path = os.path.join(current_app.config['UPLOAD_FOLDER'], video_filename)
        music_path = os.path.join(current_app.config['UPLOAD_FOLDER'], music_filename)
        
        video_file.save(video_path)
        music_file.save(music_path)
        
        try:
            # 添加背景音乐
            video_service = get_video_service()
            result = video_service.add_background_music_with_options_service(
                video_path, music_path, volume_ratio, loop_music,
                fade_in_duration, fade_out_duration, start_time, end_time
            )
            
            if not result['success']:
                return jsonify({'error': result['error']}), 500
            
            output_path = result['output_path']
            
            # 清理临时文件
            os.remove(video_path)
            os.remove(music_path)
            
            return send_file(output_path, as_attachment=True, download_name='video_with_bg_music.mp4')
            
        except Exception as e:
            # 清理临时文件
            if os.path.exists(video_path):
                os.remove(video_path)
            if os.path.exists(music_path):
                os.remove(music_path)
            raise e
    
    except Exception as e:
        logging.error(f"添加背景音乐失败: {e}")
        return jsonify({'error': str(e)}), 500 

@video_bp.route('/merge_audio', methods=['POST'])
def merge_video_audio():
    """合并视频和音频"""
    try:
        # 检查是否有视频文件
        if 'video' not in request.files:
            return jsonify({'error': '没有上传视频文件'}), 400
        
        # 检查是否有音频文件
        if 'audio' not in request.files:
            return jsonify({'error': '没有上传音频文件'}), 400
        
        video_file = request.files['video']
        audio_file = request.files['audio']
        
        if video_file.filename == '' or audio_file.filename == '':
            return jsonify({'error': '没有选择文件'}), 400
        
        # 检查文件格式
        if not allowed_file(video_file.filename, current_app.config['ALLOWED_EXTENSIONS']):
            return jsonify({'error': '不支持的视频文件格式'}), 400
        
        if not allowed_file(audio_file.filename, current_app.config['ALLOWED_AUDIO_EXTENSIONS']):
            return jsonify({'error': '不支持的音频文件格式'}), 400
        
        # 获取参数
        merge_type = request.form.get('merge_type', 'mix')  # 'mix' 或 'replace'
        original_volume = float(request.form.get('original_volume', 1.0))
        new_audio_volume = float(request.form.get('new_audio_volume', 1.0))
        fade_in_duration = float(request.form.get('fade_in_duration', 0))
        fade_out_duration = float(request.form.get('fade_out_duration', 0))
        
        # 获取预览设置
        generate_preview = request.form.get('generate_preview', 'false').lower() == 'true'
        preview_duration = request.form.get('preview_duration', 10, type=int)  # 默认10秒
        
        # 验证参数
        if merge_type not in ['mix', 'replace']:
            return jsonify({'error': '合并类型必须是 mix 或 replace'}), 400
        
        if not (0.0 <= original_volume <= 2.0):
            return jsonify({'error': '原音频音量必须在 0.0-2.0 范围内'}), 400
        
        if not (0.0 <= new_audio_volume <= 2.0):
            return jsonify({'error': '新音频音量必须在 0.0-2.0 范围内'}), 400
        
        if fade_in_duration < 0 or fade_out_duration < 0:
            return jsonify({'error': '淡入淡出时长不能为负数'}), 400
        
        # 保存上传的文件
        video_filename = get_safe_filename(video_file.filename)
        audio_filename = get_safe_filename(audio_file.filename)
        
        video_path = os.path.join(current_app.config['UPLOAD_FOLDER'], video_filename)
        audio_path = os.path.join(current_app.config['UPLOAD_FOLDER'], audio_filename)
        
        video_file.save(video_path)
        audio_file.save(audio_path)
        
        try:
            # 合并视频和音频
            video_service = get_video_service()
            
            # 如果需要生成预览视频，将预览时长传递给服务
            if generate_preview:
                result = video_service.merge_video_audio_service(
                    video_path, audio_path, merge_type, original_volume, 
                    new_audio_volume, fade_in_duration, fade_out_duration,
                    preview_duration=preview_duration
                )
            else:
                result = video_service.merge_video_audio_service(
                    video_path, audio_path, merge_type, original_volume, 
                    new_audio_volume, fade_in_duration, fade_out_duration
                )
            
            if not result['success']:
                return jsonify({'error': result['error']}), 500
            
            output_path = result['output_path']
            
            # 清理临时文件
            os.remove(video_path)
            os.remove(audio_path)
            
            return send_file(output_path, as_attachment=True, download_name='merged_video_audio.mp4')
            
        except Exception as e:
            # 清理临时文件
            if os.path.exists(video_path):
                os.remove(video_path)
            if os.path.exists(audio_path):
                os.remove(audio_path)
            raise e
    
    except Exception as e:
        logging.error(f"视频音频合并失败: {e}")
        return jsonify({'error': str(e)}), 500 